package com.gzcstec.stmp.service.impl;

import com.gzcstec.stmp.config.StmpServerConfig;
import com.gzcstec.stmp.factory.StmpPool;
import com.gzcstec.stmp.service.MailSender;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.StringWriter;
import java.util.Map;

@Component
public class MailSenderImpl implements MailSender {

    private static Logger logger = LoggerFactory.getLogger(MailSenderImpl.class);

    /**
     * 引入邮件服务器配置信息
     */
    @Autowired
    private StmpServerConfig stmpServerConfig;

    /**
     * 注入邮箱session连接池对象
     */
    @Autowired
    private StmpPool stmpPool;

    @Override
    public void sendMail(String[] to, String subject, String content , String filePath) {
        Session session = null;
        try {
            session = initMimeMessage();
            // 发送消息
            Transport.send(_setContent(_setSenderInfo(session ,subject , to) , content , filePath));
        }catch (Exception e) {
            e.printStackTrace();
            logger.debug("发送邮件失败,e={}" , e.getMessage());
        }finally {
            if(session != null) {
                stmpPool.returnObject(session);
            }
        }
    }

    @Override
    public void sendMail4Template(String[] to, String subject, String tempalteName, Map paras , String filePath) {
        Session session = null;
        try {
            // 设置消息体
            String mailBody = "";
            Version version = new Version("2.3.0");
            Configuration cfg = new Configuration(version);
            cfg.setDefaultEncoding("UTF-8");
            cfg.setClassForTemplateLoading(this.getClass() , "/templates");

            Template t = cfg.getTemplate(tempalteName);
            StringWriter writer = new StringWriter();
            t.process(paras , writer);
            mailBody = writer.toString();

            session = initMimeMessage();
            // 发送消息
            Transport.send(_setContent(_setSenderInfo(session ,subject , to) , mailBody , filePath));
        }catch (Exception e) {
            e.printStackTrace();
            logger.debug("发送邮件失败,e={}" , e.getMessage());
        }finally {
            if(session != null) {
                stmpPool.returnObject(session);
            }
        }
    }

    @Override
    public Session initMimeMessage() throws Exception {
        return stmpPool.borrowObject();
    }

    /**
     * 设置邮件消息主题内容
     * @param message 邮件回话session
     * @param content 邮件正文信息
     * @param filePath 附件路径
     * @return
     * @throws MessagingException
     */
    private Message _setContent(Message message , String content , String filePath) throws Exception {
        if(StringUtils.isEmpty(filePath)) {
            //没有带附件的发送邮件
            message.setContent(content , "text/html;charset=UTF-8");
        }else {
            //带附件的发送邮件
            File file = new File(filePath);
            if(file.exists()) {
                //附件存在时才添加附件
                // 创建消息部分
                BodyPart messageBodyPart = new MimeBodyPart();

                // 消息
                messageBodyPart.setContent(content , "text/html;charset=UTF-8");

                // 创建多重消息
                Multipart multipart = new MimeMultipart();

                // 设置文本消息部分
                multipart.addBodyPart(messageBodyPart);

                // 附件部分
                messageBodyPart = new MimeBodyPart();
                DataSource source = new FileDataSource(file);
                messageBodyPart.setDataHandler(new DataHandler(source));
                messageBodyPart.setFileName(file.getName());
                multipart.addBodyPart(messageBodyPart);

                // 发送完整消息
                message.setContent(multipart );
            }
        }
        return message;
    }

    /**
     * 设置邮件发件人信息
     * @param session 邮箱回话
     * @param subject
     * @param to
     * @return
     * @throws MessagingException
     */
    private Message _setSenderInfo(Session session ,String subject , String[] to) throws Exception {

        // 创建默认的 MimeMessage 对象
        MimeMessage message = new MimeMessage(session);

        // Set From: 设置发件人信息
        message.setFrom(new InternetAddress(stmpServerConfig.getSender() , stmpServerConfig.getNickname() , "UTF-8"));

        // Set To: 设置接收人信息
        message.addRecipients(Message.RecipientType.TO, org.apache.commons.lang3.StringUtils.join(to , ","));

        // Set Subject: 设置邮件标题
        message.setSubject(subject , "UTF-8");

        return message;
    }
}
